/**
 * Copyright (c) [2025] [AGIROS] 
 * [travoddsgen] is licensed under Mulan PSL v2. 
 * You can use this software according to the terms and conditions of the Mulan PSL v2. 
 * You may obtain a copy of Mulan PSL v2 at: 
 *          http://license.coscl.org.cn/MulanPSL2 
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 
 * See the Mulan PSL v2 for more details.
 */ 

#include "CLangTypeSourceVisitor.h"
#include "CLangTypeNameVisitor.h"
#include <fstream>

CLangTypeSourceVisitor::CLangTypeSourceVisitor(
    const std::string& outputDir, 
    const std::string& fileName, 
    CLangTypeNameVisitor* typeNameVisitor,
    CLangTypeHeaderVisitor* headerVisitor)
    : FileGenVisitor(outputDir, fileName),
      typeNameVisitor_(typeNameVisitor),
      headerVisitor_(headerVisitor) {
}

void CLangTypeSourceVisitor::generateSequenceImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    std::string sequenceImpl = "DDSCSequenceImpl(" + structName + ");\n";
    content_ += sequenceImpl;
    content_ += "\n";
}

void CLangTypeSourceVisitor::generateMapImpl() {
    for (auto& mapType : headerVisitor_->getDecledMapTypes()) {
        std::string mapTypeStr = mapType.first;
        size_t pos = mapTypeStr.find("#");
        std::string keyTypeName = mapTypeStr.substr(0, pos);
        std::string valueTypeName = mapTypeStr.substr(pos + 1);
        std::string mapName = keyTypeName + "_" + valueTypeName;
        std::string mapImpl = "DDSCMapImpl(" + keyTypeName + ", " + valueTypeName + ");\n";
        content_ += mapImpl;
        content_ += "\n";
    }
}

void CLangTypeSourceVisitor::visit(SpecificationNode& node) {
    std::string headerFile = headerVisitor_->getFileName();
    // 文件头的宏声明
    std::string headers = "#include \"" + headerFile + "\"\n";
    headers += "#include \"dds_basetype.h\"\n";
    headers += "#include \"dds_c_string.h\"\n";
    headers += "#include \"dds_c_sequence.cpp\"\n";
    headers += "#include \"dds_c_map.cpp\"\n";
    content_ += headers + "\n";

    // __cplusplus宏定义开始
    content_ += "#ifdef __cplusplus\n";
    content_ += "extern \"C\" {\n";
    content_ += "#endif\n\n";

    // 生成Map类型的实现定义
    generateMapImpl();

    // 递归访问子节点
    if (node.definitions_) {
        node.definitions_->accept(*this);
    }

    // __cplusplus宏定义结尾
    content_ += "#ifdef __cplusplus\n";
    content_ += "}\n";
    content_ += "#endif\n";

    // 将_content写入文件
    writeToFile();
}

void CLangTypeSourceVisitor::visit(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    // 生成sequence类型的实现定义
    generateSequenceImpl(node);
    // 生成构造函数实现
    // generateConstructorImpl(node);
    // 生成析构函数实现
    // generateDestructorImpl(node);
    // 生成拷贝构造函数实现
    // generateCopyConstructorImpl(node);
    // 生成赋值操作符实现
    // generateAssignmentOperatorImpl(node);
    // _create函数实现
    generateCreateFuncImpl(node);
    // _destroy函数实现
    generateDestroyFuncImpl(node);
    // _copy函数实现
    generateCopyFuncImpl(node);
}

void CLangTypeSourceVisitor::generateConstructorImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "::" + structName + "() {\n";
    indentLevel_++;
    // 递归访问子节点
    for (auto member : node.members_->nodes_) {
        // // sequence类型
        // auto sequenceType = dynamic_cast<SequenceTypeNode*>(member->type_);
        // if (sequenceType) {
        //     std::string memberName = *member->identifier_;
        //     std::string memberType = typeNameVisitor_->findName(sequenceType);
        //     content_ += indent() + memberName;
        //     content_ += " = ";
        //     content_ += memberType + "_create();\n";
        // }
        // map类型
        // auto mapType = dynamic_cast<MapTypeNode*>(member->type_);
        // if (mapType) {
        //     std::string memberName = *member->identifier_;
        //     std::string memberType = typeNameVisitor_->findName(mapType);
        //     content_ += indent() + memberName;
        //     content_ += " = ";
        //     content_ += memberType + "_create();\n";
        // }
        // // string类型
        // auto stringType = dynamic_cast<StringTypeNode*>(member->type_);
        // if (stringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + memberName;
        //     content_ += " = ";
        //     content_ += "DDSCString_create();\n";
        // }
        // // wstring类型
        // auto wstringType = dynamic_cast<WideStringTypeNode*>(member->type_);
        // if (wstringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + memberName;
        //     content_ += " = ";
        //     content_ += "DDSCWString_create();\n";
        // }
    }
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateCreateFuncImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "* " + structName + "_create() {\n";
    indentLevel_++;
    content_ += indent() + "return new " + structName + "();\n";
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateDestructorImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "::~" + structName + "() {\n";
    indentLevel_++;
    // 递归访问子节点
    for (auto member : node.members_->nodes_) {
        // // sequence类型
        // auto sequenceType = dynamic_cast<SequenceTypeNode*>(member->type_);
        // if (sequenceType) {
        //     std::string memberName = *member->identifier_;
        //     std::string typeName = typeNameVisitor_->findName(sequenceType);
        //     content_ += indent() + "if (" + memberName + ") {\n";
        //     indentLevel_++;
        //     content_ += indent() + typeName + "_destroy(" + memberName + ");\n";
        //     indentLevel_--;
        //     content_ += indent() + "}\n";
        // }
        // map类型
        // auto mapType = dynamic_cast<MapTypeNode*>(member->type_);
        // if (mapType) {
        //     std::string memberName = *member->identifier_;
        //     std::string typeName = typeNameVisitor_->findName(mapType);
        //     content_ += indent() + "if (" + memberName + ") {\n";
        //     indentLevel_++;
        //     content_ += indent() + typeName + "_destroy(" + memberName + ");\n";
        //     indentLevel_--;
        //     content_ += indent() + "}\n";
        // }
        // // string类型
        // auto stringType = dynamic_cast<StringTypeNode*>(member->type_);
        // if (stringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + "if (" + memberName + ") {\n";
        //     indentLevel_++;
        //     content_ += indent() + "DDSCString_destroy(" + memberName + ");\n";
        //     indentLevel_--;
        //     content_ += indent() + "}\n";
        // }
        // // wstring类型
        // auto wstringType = dynamic_cast<WideStringTypeNode*>(member->type_);
        // if (wstringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + "if (" + memberName + ") {\n";
        //     indentLevel_++;
        //     content_ += indent() + "DDSCWString_destroy(" + memberName + ");\n";
        //     indentLevel_--;
        //     content_ += indent() + "}\n";
        // }
    }
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateDestroyFuncImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += "void " + structName + "_destroy(" + structName + "* obj) {\n";
    indentLevel_++;
    content_ += indent() + "delete obj;\n";
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateCopyConstructorImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "::" + structName + "(const " + structName + "& other) {\n";
    indentLevel_++;
    content_ += indent() + "*this = other;\n";
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateAssignmentOperatorImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "& " + structName + "::operator=(const " + structName + "& other) {\n";
    indentLevel_++;
    // 递归访问子节点
    for (auto member : node.members_->nodes_) {
        // // sequence类型
        // auto sequenceType = dynamic_cast<SequenceTypeNode*>(member->type_);
        // if (sequenceType) {
        //     std::string memberName = *member->identifier_;
        //     std::string typeName = typeNameVisitor_->findName(sequenceType);
        //     content_ += indent() + memberName + " = " + typeName + "_copy(" + memberName + ", other." + memberName + ");\n";
        // }
        // map类型
        // auto mapType = dynamic_cast<MapTypeNode*>(member->type_);
        // if (mapType) {
        //     std::string memberName = *member->identifier_;
        //     std::string typeName = typeNameVisitor_->findName(mapType);
        //     content_ += indent() + memberName + " = " + typeName + "_copy(" + memberName + ", other." + memberName + ");\n";
        // }
        // // string类型
        // auto stringType = dynamic_cast<StringTypeNode*>(member->type_);
        // if (stringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + memberName + " = DDSCString_assign(" + memberName + ", other." + memberName + ");\n";
        // }
        // // wstring类型
        // auto wstringType = dynamic_cast<WideStringTypeNode*>(member->type_);
        // if (wstringType) {
        //     std::string memberName = *member->identifier_;
        //     content_ += indent() + memberName + " = DDSCWString_assign(" + memberName + ", other." + memberName + ");\n";
        // }
    }
    content_ += "return *this;\n";
    indentLevel_--;
    content_ += "}\n\n";
}

void CLangTypeSourceVisitor::generateCopyFuncImpl(StructDefNode& node) {
    std::string structName = typeNameVisitor_->findName(&node);
    content_ += structName + "* " + structName + "_copy(" + structName + "* obj, const " + structName + "* other) {\n";
    indentLevel_++;
    content_ += indent() + "*obj = *other;\n";
    content_ += indent() + "return obj;\n";
    indentLevel_--;
    content_ += "}\n\n";
}